package com.project.quiktask.controller;
/**
 * This is the controller class that process the user input
 * @author PHAM MINH VIET
 */
import java.util.Stack;

import com.project.quiktask.util.Result;
import com.project.quiktask.util.Variable;

public class Controller {

	private final int FIRST_INDEX = 0;

	enum CommandType {
		ADD, SEARCH, VIEW, UPDATE, DELETE, UNDO, SYNC, HELP, INVALID
	};

	public static Stack<CommandHandler> undoStack;

	public Controller() {
		undoStack = new Stack<CommandHandler>();
	}

	public Result processCommand(String command) {
		CommandType commandType = determineCommandType(command);
		String commandContent = removeFirstWord(command);  // consider let handlers do this
		Result result = executeCurrentCommand(commandType, commandContent);
		return result;
	}

	public CommandType determineCommandType(String command) {

		String commandTypeString = getFirstWord(command).trim();

		if (isAddCommand(commandTypeString))
			return CommandType.ADD;
		else if (isViewCommand(commandTypeString))
			return CommandType.VIEW;
		else if (isUpdateCommand(commandTypeString))
			return CommandType.UPDATE;
		else if (isDeleteCommand(commandTypeString))
			return CommandType.DELETE;
		else if (isSearchCommand(commandTypeString))
			return CommandType.SEARCH;
		else if (isUndoCommand(commandTypeString))
			return CommandType.UNDO;
		else if (isSyncCommand(commandTypeString))
			return CommandType.SYNC;
		else if (isHelpCommand(commandTypeString))
			return CommandType.HELP;
		else 
			return CommandType.INVALID;
	}

	public Result executeCurrentCommand(CommandType commandType, String commandContent) {

		Result result;

		switch (commandType) {
		case ADD:
			AddHandler addHandler = new AddHandler();
			result = addHandler.execute(commandContent);
			undoStack.add(addHandler);
			return result;
		case SEARCH:
			SearchHandler searchHandler = new SearchHandler();
			result = searchHandler.execute(commandContent);
			undoStack.add(searchHandler);
			return result;
		case DELETE:
			DeleteHandler deleteHandler = new DeleteHandler();
			result = deleteHandler.execute(commandContent);
			//if (!result.getFeedback().equals(Variable.FEEDBACK_MANY_TASKS_WITH_SAME_KEYWORD)) {
			undoStack.add(deleteHandler);
			//}
			return result;		
		case UPDATE:
			UpdateHandler updateHandler = new UpdateHandler();
			result = updateHandler.execute(commandContent);
			if (!result.getFeedback().equals(Variable.FEEDBACK_MANY_TASKS_WITH_SAME_KEYWORD)) {
				undoStack.add(updateHandler);
			}
			return result;
		case VIEW:
			ViewHandler viewHandler = new ViewHandler();
			result = viewHandler.execute(commandContent);
			undoStack.add(viewHandler);
			return result;
		case UNDO:
			if (!undoStack.isEmpty()) {
				CommandHandler undohandHandler = undoStack.pop();
				result=undohandHandler.undo();
			} else {
				return new Result("No actions to be undone.");
			}
			return result;
		case SYNC:
			return null;
		case HELP:
			return null;
		default:
			return new Result(Variable.FEEDBACK_COMMAND_INVALID);
		}
	}

	public boolean isAddCommand(String commandTypeString) {
		if (commandTypeString.equalsIgnoreCase("add") ||
				commandTypeString.equalsIgnoreCase("a"))
			return true;
		else  
			return false;

	}

	public boolean isViewCommand(String commandTypeString) {
		if (commandTypeString.equalsIgnoreCase("view") ||
				commandTypeString.equalsIgnoreCase("v"))
			return true;
		else 
			return false;
	}

	public boolean isUpdateCommand(String commandTypeString) {
		if (commandTypeString.equalsIgnoreCase("update") ||
				commandTypeString.equalsIgnoreCase("up"))
			return true;
		else 
			return false;
	}

	public boolean isDeleteCommand(String commandTypeString) {
		if (commandTypeString.equalsIgnoreCase("delete") ||
				commandTypeString.equalsIgnoreCase("d"))
			return true;
		else 
			return false;
	}

	public boolean isSearchCommand(String commandTypeString) {
		if (commandTypeString.equalsIgnoreCase("search") ||
				commandTypeString.equalsIgnoreCase("sc"))
			return true;
		else 
			return false;
	}

	public boolean isUndoCommand(String commandTypeString) {
		if (commandTypeString.equalsIgnoreCase("undo") ||
				commandTypeString.equalsIgnoreCase("un"))
			return true;
		else 
			return false;
	}

	public boolean isSyncCommand(String commandTypeString) {
		if (commandTypeString.equalsIgnoreCase("sync") ||
				commandTypeString.equalsIgnoreCase("sy"))
			return true;
		else 
			return false;
	}
	
	public boolean isHelpCommand(String commandTypeString) {
		if (commandTypeString.equalsIgnoreCase("help") ||
				commandTypeString.equalsIgnoreCase("h"))
			return true;
		else 
			return false;
	}
	
	private String getFirstWord(String userCommandLine) {
		userCommandLine = userCommandLine.trim();
		String[] splitCommand = userCommandLine.split("\\s+");
		String firstWord = splitCommand[FIRST_INDEX];
		return firstWord;
	}

	private String removeFirstWord(String userCommand) {
		return userCommand.replace(getFirstWord(userCommand), "").trim();
	}

}
